﻿using netcore_comm.Redis;
using netcore_service.Dto;
using netcore_service.IService;
using netcore_service.Model;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace netcore_service.Service
{
    public class UserConnectionManager : IUserConnectionManager
    {
        private readonly RedisHelper _redisHelper;
        public UserConnectionManager(
            RedisHelper redisHelper
            )
        {
            this._redisHelper = redisHelper;
        }
        private static readonly ConcurrentDictionary<string, UserConnectionInfo> _userConnections = new();


        private class UserConnectionInfo
        {
            public string UserId { get; set; } = string.Empty;
            public string School { get; set; }
            public UserRole Role { get; set; }
            public List<string> ConnectionIds { get; set; } = new();
        }

        public async Task AddConnection(string userId, string connectionId, UserRole role, string school)
        {
            await _redisHelper.HashSetAsync("userId", userId,
                new UserConnectionInfo { UserId = userId, Role = role, School = school, ConnectionIds = { connectionId } });
        }

        public async Task RemoveConnection(string connectionId)
        {
            var user = await _redisHelper.HashGetAllAsync<UserConnectionInfo>("userId");
            var userInfo = user.Values.FirstOrDefault(info => info.ConnectionIds.Contains(connectionId));
            if (userInfo != null)
            {
                userInfo.ConnectionIds.Remove(connectionId);
                if (userInfo.ConnectionIds.Count == 0)
                {
                    //_userConnections.TryRemove(userInfo.UserId, out _);
                    await _redisHelper.HashDeleteAsync("userId", userInfo.UserId);
                }
                else
                {
                    await _redisHelper.HashSetAsync("userId", userInfo.UserId, userInfo);
                }
            }
        }

        public async Task<List<string>> GetUserConnections(string userId)
        {
            var user = await _redisHelper.HashGetAsync<UserConnectionInfo>("userId", userId);
            return user != null ? user.ConnectionIds : new List<string>();
        }

        public async Task<List<string>> GetOnlineAgents(string school)
        {
            var user = await _redisHelper.HashGetAllAsync<UserConnectionInfo>("userId");

            return user.Values
                .Where(info => info.Role == UserRole.Agent && info.School == school && info.ConnectionIds.Count > 0)
                .Select(info => info.UserId)
                .ToList();
        }

        public async Task<List<string>> GetOnlineCustomers()
        {
            var user = await _redisHelper.HashGetAllAsync<UserConnectionInfo>("userId");

            return user.Values
                .Where(info => info.Role == UserRole.Customer && info.ConnectionIds.Count > 0)
                .Select(info => info.UserId)
                .ToList();
        }

        public async Task<string?> GetUserIdByConnection(string connectionId)
        {
            var user = await _redisHelper.HashGetAllAsync<UserConnectionInfo>("userId");

            return user.Values
                .FirstOrDefault(info => info.ConnectionIds.Contains(connectionId))?.UserId;
        }
    }
}
